/**
* @file        ut_signal_format
* @brief       
* @version     1.0.0
* @author      Changlin.Jing 
* @date        2023/7/28 9:07
* @copyright   Copyright  2022 Langge Software Co., Ltd. All rights reserved.
*/
#include <string>
#include "ut_signal_format.hpp"
#include "ut_string.hpp"
#include "osapi.h"
BEGIN_SPACE_LANGE_VDR

void UTSignalFormat::ConvertSignalToString(char *res, const std::shared_ptr<I_LOC_SIGNAL> &signal) {
    if(signal->mLocalSignalType == ACC_SIGNAL){
        std::shared_ptr<LOC_ACC_SIGNAL> convertSignal = std::static_pointer_cast<LOC_ACC_SIGNAL>(signal);
        ossnprintf(res,1024,"%s\t%lld,%lf,%lf,%lf,%f",
                   "@ACC",
                   convertSignal->mLocalTickTime,
                   convertSignal->mOriginX,
                   convertSignal->mOriginY,
                   convertSignal->mOriginZ,
                   convertSignal->mTimeGap
        );
    }
    if(signal->mLocalSignalType == GYRO_SIGNAL){
        std::shared_ptr<LOC_GYRO_SIGNAL> convertSignal = std::static_pointer_cast<LOC_GYRO_SIGNAL>(signal);
        ossnprintf(res,1024,"%s\t%lld,%lf,%lf,%lf,%f",
                   "@GYR",
                   convertSignal->mLocalTickTime,
                   convertSignal->mOriginX,
                   convertSignal->mOriginY,
                   convertSignal->mOriginZ,
                   convertSignal->mTimeGap
        );
    }
    if(signal->mLocalSignalType == MAGN_SIGNAL){
        std::shared_ptr<LOC_MAGN_SIGNAL> convertSignal = std::static_pointer_cast<LOC_MAGN_SIGNAL>(signal);
        ossnprintf(res,1024,"%s\t%lld,%lf,%lf,%lf,%f",
                   "@MAG",
                   convertSignal->mLocalTickTime,
                   convertSignal->mOriginX,
                   convertSignal->mOriginY,
                   convertSignal->mOriginZ,
                   convertSignal->mTimeGap
        );
    }
    if(signal->mLocalSignalType == POS_SIGNAL){
        std::shared_ptr<LOC_POS_SIGNAL> convertSignal = std::static_pointer_cast<LOC_POS_SIGNAL>(signal);
        ossnprintf(res,1024,"%s\t%lld,%lld,%d,%.7f,%.7f,%lf,%lf,%lf,%lf,%lf,%lf,%f,%d",
                   "@POS",
                   convertSignal->mLocalTickTime,
                   convertSignal->mUtcTickTime,
                   (int)convertSignal->mLocType,
                   convertSignal->mLongitude,
                   convertSignal->mLatitude,
                   convertSignal->mSpeed,
                   convertSignal->mHeading,
                   convertSignal->mHeight,
                   convertSignal->mAccuracyVelocity,
                   convertSignal->mAccuracyLocHorizoon,
                   convertSignal->mAccuracyLocVertical,
                   convertSignal->mAccuracyAngularVelocity,
                   convertSignal->mValidSatCount


        );
    }
    if(signal->mLocalSignalType == ROTATION_SIGNAL){
        std::shared_ptr<LOC_ROTATION_SIGNAL> convertSignal = std::static_pointer_cast<LOC_ROTATION_SIGNAL>(signal);
        ossnprintf(res,1024,"%s\t%lld,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf",
                   "@ROT",
                   convertSignal->mLocalTickTime,
                   convertSignal->mX,
                   convertSignal->mY,
                   convertSignal->mZ,
                   convertSignal->mRotation[0],
                   convertSignal->mRotation[1],
                   convertSignal->mRotation[2],
                   convertSignal->mRotation[3],
                   convertSignal->mRotation[4],
                   convertSignal->mRotation[5],
                   convertSignal->mRotation[6],
                   convertSignal->mRotation[7],
                   convertSignal->mRotation[8]

        );
    }

    if(signal->mLocalSignalType == SATELLITE_SIGNAL){
        std::shared_ptr<LOC_SATELLITE_SIGNAL> convertSignal = std::static_pointer_cast<LOC_SATELLITE_SIGNAL>(signal);
        ossnprintf(res,1024,"%s\t%lld,%d,%d",
                   "@SAT",
                   convertSignal->mLocalTickTime,
                   convertSignal->m_iTotal,
                   convertSignal->m_iAvailableCount
        );

        char* p = res + osstrlen(res);
        for(int32_t i= 0;i<convertSignal->m_iTotal;i++){
            auto &sat = convertSignal->m_aSat[i];
            ossnprintf(p,50,"\t%.3f,%.3f,%.3f,%d,%d,%d",
                       sat.m_dAzimuth,
                       sat.m_dElevation,
                       sat.m_dSNR,
                       sat.m_iSVID,
                       sat.m_iType,
                       sat.m_iSAvaliable
            );
            p = res + osstrlen(res);
        }
        //sprintf(p,"%s","\n");
    }

    if (signal->mLocalSignalType == FUSE_SIGNAL) {
        std::shared_ptr<LOC_POS_SIGNAL> convertSignal = std::static_pointer_cast<LOC_POS_SIGNAL>(signal);
        ossnprintf(res, 1024, "%s\t%lld,%lld,%d,%.7f,%.7f,%lf,%lf,%lf,%lf,%lf,%lf,%f,%d," \
                            "%d,%d,%f,%f,%f",
                   "@LOC",
                   convertSignal->mLocalTickTime,
                   convertSignal->mUtcTickTime,
                   (int) convertSignal->mLocType,
                   convertSignal->mLongitude,
                   convertSignal->mLatitude,
                   convertSignal->mSpeed,
                   convertSignal->mHeading,
                   convertSignal->mHeight,
                   convertSignal->mAccuracyVelocity,
                   convertSignal->mAccuracyLocHorizoon,
                   convertSignal->mAccuracyLocVertical,
                   convertSignal->mAccuracyAngularVelocity,
                   convertSignal->mValidSatCount,

                   convertSignal->mLonLatSrc,
                   convertSignal->mSpeedSrc,
                   convertSignal->mPitch,
                   convertSignal->mRoll,
                   convertSignal->mYawDiff
        );
    }
    if (signal->mLocalSignalType == CAR_SIGNAL)
    {
        std::shared_ptr<LOC_CAR_SIGNAL> convertSignal = std::static_pointer_cast<LOC_CAR_SIGNAL>(signal);
        ossnprintf(res, 1024, "%s\t%lld,%lld,%.3f,%.3f",
                   "@CAR",
                   convertSignal->mLocalTickTime,
                   convertSignal->mCarTimestamp,
                   convertSignal->mRealSpeed,
                   convertSignal->mTimeGap);
    }

}

std::shared_ptr<I_LOC_SIGNAL> UTSignalFormat::ConvertStringToSignal(char *data) {
    std::string input = std::string( vdr::StringUtils::rtrim(data));
    std::string header =  input.substr(0,4);
    if(header =="@POS"){
        std::shared_ptr<LOC_POS_SIGNAL> signal = std::make_shared<LOC_POS_SIGNAL>();
        auto body = input.substr(5,input.length()-1);
        std::vector<std::string> res;
        vdr::StringUtils::SplitString(body,",",res);
        signal->mLocalTickTime = std::stoll(res[0]);
        signal->mUtcTickTime = std::stoll(res[1]);
        signal->mLocType = (LOC_TYPE)(std::stoi (res[2]));
        signal->mLongitude = std::stod(res[3]);
        signal->mLatitude = std::stod(res[4]);
        signal->mSpeed = std::stod(res[5]);
        signal->mHeading = std::stod(res[6]);
        signal->mHeight = std::stod(res[7]);
        signal->mAccuracyVelocity = std::stod(res[8]);
        signal->mAccuracyLocHorizoon = std::stod(res[9]);
        signal->mAccuracyLocVertical = std::stod(res[10]);
        signal->mAccuracyAngularVelocity = std::stod(res[11]);
        signal->mValidSatCount = std::stoi(res[12]);

        return signal;
    }
    if(header == "@SAT"){
        std::shared_ptr<LOC_SATELLITE_SIGNAL> signal = std::make_shared<LOC_SATELLITE_SIGNAL>();
        auto body = input.substr(5,input.length()-1);
        std::vector<std::string> res;
       vdr::StringUtils::SplitString(body,"\t",res);
        std::vector<std::string> summary;
       vdr::StringUtils::SplitString(res[0],",",summary);
        signal->mLocalTickTime = std::stoll(summary[0]);
        signal->m_iTotal = std::stoi(summary[1]);
        signal->m_iAvailableCount = std::stoi(summary[2]);

        for(int i=1;i<res.size();i++){
            std::vector<std::string> dd;
           vdr::StringUtils::SplitString(res[i],",",dd);
            signal->m_aSat[i-1].m_dAzimuth = std::stod(dd[0]);
            signal->m_aSat[i-1].m_dElevation =  std::stod(dd[1]);
            signal->m_aSat[i-1].m_dSNR =  std::stod(dd[2]);
            signal->m_aSat[i-1].m_iSVID =  std::stoi(dd[3]);
            signal->m_aSat[i-1].m_iType =  std::stoi(dd[4]);
            if(dd.size()>5){
                signal->m_aSat[i-1].m_iSAvaliable =  std::stoi(dd[5]);
            }
        }

        return signal;
    }
    if(header == "@ACC"){
        std::shared_ptr<LOC_ACC_SIGNAL> signal = std::make_shared<LOC_ACC_SIGNAL>();
        auto body = input.substr(5,input.length()-1);
        std::vector<std::string> res;
       vdr::StringUtils::SplitString(body,",",res);
        signal->mLocalTickTime = std::stoll(res[0]);
        signal->mOriginX = std::stof(res[1]);
        signal->mOriginY = std::stof(res[2]);
        signal->mOriginZ = std::stof(res[3]);
        return signal;
    }
    if(header == "@GYR"){
        std::shared_ptr<LOC_GYRO_SIGNAL> signal = std::make_shared<LOC_GYRO_SIGNAL>();
        auto body = input.substr(5,input.length()-1);
        std::vector<std::string> res;
       vdr::StringUtils::SplitString(body,",",res);
        signal->mLocalTickTime = std::stoll(res[0]);
        signal->mOriginX = std::stof(res[1]);
        signal->mOriginY = std::stof(res[2]);
        signal->mOriginZ = std::stof(res[3]);
        return signal;
    }
    if(header == "@MAG"){
        std::shared_ptr<LOC_MAGN_SIGNAL> signal = std::make_shared<LOC_MAGN_SIGNAL>();
        auto body = input.substr(5,input.length()-1);
        std::vector<std::string> res;
       vdr::StringUtils::SplitString(body,",",res);
        signal->mLocalTickTime = std::stoll(res[0]);
        signal->mOriginX = std::stof(res[1]);
        signal->mOriginY = std::stof(res[2]);
        signal->mOriginZ = std::stof(res[3]);
        return signal;
    }
    if(header == "@ROT"){
        std::shared_ptr<LOC_ROTATION_SIGNAL> signal = std::make_shared<LOC_ROTATION_SIGNAL>();
        auto body = input.substr(5,input.length()-1);
        std::vector<std::string> res ;
       vdr::StringUtils::SplitString(body,",",res);
        signal->mLocalTickTime = std::stoll(res[0]);
        signal->mX= std::stof(res[1]);
        signal->mY = std::stof(res[2]);
        signal->mZ = std::stof(res[3]);
        if(res.size() >=12){
            for(int i=0;i<9;i++){
                signal->mRotation[i] = std::stof(res[4+i]);
            }
        }
        return signal;
    }
    //turn into car loc_car_signal
    if (header == "@CAR"){
        std::shared_ptr<LOC_CAR_SIGNAL> signal = std::make_shared<LOC_CAR_SIGNAL>();
        auto body = input.substr(5, input.length() - 1);
        std::vector<std::string> res;

       vdr::StringUtils::SplitString(body, ",",res);
        signal->mLocalTickTime = std::stoll(res[0]);      // timestamp;
        signal->mCarTimestamp = signal->mLocalTickTime;
        signal->mRealSpeed = std::stod(res[2]);        // vehspdlgta;
        return signal;
    }
    return nullptr;
}
END_SPACE_LANGE_VDR